package com.github.thinwonton.assembly.startup;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.AprLifecycleListener;
import org.apache.catalina.core.JreMemoryLeakPreventionListener;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.http11.Http11NioProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;

/**
 * 启动参数说明：<br/>
 * server.port：tomcat端口 <br/>
 * server.docPath:WEB-INF所在的文件夹路径 <br/>
 * Created by hugo on 2017/6/15.
 */
public class TomcatBootstrap {
    private static final Logger LOGGER = LoggerFactory.getLogger(TomcatBootstrap.class);

    public static void main(String[] args) throws Exception {

        //提升性能(https://wiki.apache.org/tomcat/HowTo/FasterStartUp)
        System.setProperty("tomcat.util.scan.StandardJarScanFilter.jarsToSkip", "*.jar");
        //System.setProperty("securerandom.source","file:/dev/./urandom");

        int port = Integer.parseInt(System.getProperty("server.port", "8080")); //端口

        String contextPath = System.getProperty("server.contextPath", ""); //上下文路径

        String docPath = System.getProperty("server.docPath", getDefaultDocPath()); //

        LOGGER.info("server port : {}, context path : {},doc path : {}", port, contextPath, docPath);

        Tomcat tomcat = createTomcat(port, contextPath, docPath);
        tomcat.start();
        LOGGER.info("tomcat started");
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                try {
                    tomcat.stop();
                } catch (LifecycleException e) {
                    LOGGER.error("stoptomcat error.", e);
                }
            }
        });
        tomcat.getServer().await();
    }

    private static String getDefaultDocPath() {
        File projectDir = getProjectDir();
        String path = new StringBuffer().append("src").append(File.separator).append("main").append(File
                .separator).append("webapp").toString(); // "src/main/webapp"
        return new File(projectDir, path).getPath();
    }

    private static File getProjectDir() {
        File classpathDir = getClasspathDir();
        return classpathDir.getParentFile().getParentFile();
    }

    private static File getClasspathDir() {
        return new File(Thread.currentThread().getContextClassLoader().getResource(".").getFile());
    }

    private static Tomcat createTomcat(int port, String contextPath, String docPath) throws Exception {
        Tomcat tomcat = new Tomcat();
        String tmpdir = System.getProperty("java.io.tmpdir");
        tomcat.setBaseDir(tmpdir);
        tomcat.getHost().setAppBase(tmpdir);
        tomcat.getHost().setAutoDeploy(false);
        tomcat.getHost().setDeployOnStartup(false);
        tomcat.getEngine().setBackgroundProcessorDelay(-1);
        tomcat.setConnector(newNioConnector());
        tomcat.getConnector().setPort(port);
        tomcat.getService().addConnector(tomcat.getConnector());
        Context context = tomcat.addWebapp(contextPath, docPath);
        StandardServer server = (StandardServer) tomcat.getServer();
        //APR library loader. Documentation at /docs/apr.html
        server.addLifecycleListener(new AprLifecycleListener());
        //Prevent memory leaks due to use of particularjava/javax APIs
        server.addLifecycleListener(new JreMemoryLeakPreventionListener());
        return tomcat;
    }

    //在这里调整参数优化
    private static Connector newNioConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
        return connector;
    }

}
